home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr10 / 184_01.zip / FL3.MAC < prev    next >
Text File  |  1993-06-13  |  13KB  |  535 lines

  1. ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  2. ;
  3. ;This file contains the third of three patches to the 
  4. ;source code for FLTLIB to enable use of the AMD9511 
  5. ;(Intel 8231A) for floating point multiply/divide 
  6. ;and MATHLIB functions.
  7. ;N.T.Carnevale 8/84.
  8. ;
  9. ;
  10. ;See accompanying documentation.  Other useful information
  11. ;is in my article "Faster floating point math," which appeared
  12. ;on pp.46-54 of the Nov/Dec 1985 issue of Micro/Systems Journal.
  13. ;
  14. ;Use the following code to replace the source of the FLTLIB
  15. ;section of FLOATLIB.ASM from the line labelled fmult3: 
  16. ;through the line just before label pophrt:
  17. ;
  18.     ;
  19.     ;
  20. CR    EQU 0DH
  21. LF    EQU 0AH
  22. BDOS    EQU 5
  23. BOOT    EQU 0
  24. PSTRNG    EQU 9
  25.     ;
  26.     ;
  27.     ;send message to console
  28. PRMSG:
  29.     PUSH PSW
  30.     PUSH B
  31.     PUSH D
  32.     PUSH H
  33.     MVI C,PSTRNG
  34.     CALL BDOS
  35.     POP H
  36.     POP D
  37.     POP B
  38.     POP PSW
  39.     RET
  40.     ;
  41. ;**************************************************************
  42.     ;
  43.     ;
  44.     ;Port addresses
  45.     ;
  46. BASE    EQU 050H    ;base address of Compupro SS1 board
  47. CREG    EQU BASE+9    ;location of 9511's control & data ports
  48. DREG    EQU BASE+8
  49.     ;
  50.     ;
  51.     ;FPP error codes
  52.     ;
  53. ERRBITS EQU 1EH     ;the status register's error bits
  54. OVRFLO    EQU 2        ;overflow
  55. UNRFLO    EQU 4        ;underflow
  56. NEGARG    EQU 8        ;negative argument to sqrt or log function
  57. DIVZER    EQU 10H     ;divide by zero
  58. TOOBIG    EQU 18H     ;arg of asin, acos, or exp too big
  59.     ;
  60.     ;
  61.     ;FPP command codes
  62.     ;
  63. FMUL    EQU 12H
  64. FDIV    EQU 13H
  65. XCHF    EQU 19H     ;swap top two locations in fpp's stack
  66. FSQRT    EQU 1
  67. FSIN    EQU 2
  68. FCOS    EQU 3
  69. FTAN    EQU 4
  70. FASIN    EQU 5
  71. FACOS    EQU 6
  72. FATAN    EQU 7
  73. FLOG    EQU 8        ;log base 10
  74. FLN    EQU 9        ;natural logarithm
  75. FEXP    EQU 0AH     ;e^x
  76. FPWR    EQU 0BH     ;x^y
  77.     ;
  78. ;**************************************************************
  79. ;**************************************************************
  80. ;
  81. ;
  82. ;note:    timing indicated for some of the following
  83. ;
  84. ;This block converts c80 float in BD to FPP format, then loads it into FPP.  
  85. ;If out of range for FPP, aborts with warning.
  86. ;
  87. ;Data format conversion routine C2AMD--
  88. ;converts c80's float to amd's fp format.
  89. ;Based on suggestions by J.Shook, Electronics Lab, Dept.of Chemistry,
  90. ;SUNY Stony Brook
  91. ;
  92. ;Floating point formats
  93. ;----------------------
  94. ;C80 stores floats as:
  95. ;     mantissa sign in C7
  96. ;     mantissa  =  24 bit two's complement in CDE, 
  97. ;             with bit 23 assumed = 1.
  98. ;     exponent is added to 128 (80H) and stored in B.  
  99. ;             If the number is 0, B=0.
  100. ;
  101. ;FPP stores floats as:
  102. ;     mantissa sign in B7
  103. ;     mantissa  =  24 bit two's complement in CDE,
  104. ;             with bit 23 = 1.  However, 
  105. ;             the value 0 is represented by BD=0.
  106. ;     exponent sign in B6
  107. ;     exponent in B5-B0 (only 6 bits).
  108. ;
  109. ;
  110.     ;Call with value to convert in BD.
  111. C2AMD:
  112.     MOV A,B     ; 4
  113.     ORA A        ; 4
  114.     JZ FPPZERO    ;10--B=0 implies x=0
  115.     ;does exponent lie in FPP's range?
  116.     CPI 64+80H      ; 7
  117.     JNC EXPHI    ;10--exceeds 2^63
  118.     CPI -64+80H     ; 7
  119.     JC EXPLO    ;10--smaller than 2^-64
  120.     ;exponent ok, proceed
  121.     SUI 80H        ; 7--corrects exponent
  122.     ANI 7FH     ; 7--mask out hi bit of B
  123.     MOV B,A     ; 4-- and save til later
  124.     MOV A,C     ; 4
  125.     ANI 80H     ; 7--isolate mantissa sign bit
  126.     ORA B        ; 4--fix mantissa sign bit for FPP
  127.     MOV B,A     ; 4--done with B
  128.     ;take care of C
  129.     MVI A,80H    ; 7
  130.     ORA C        ; 4--set hi bit of C
  131.     MOV C,A     ; 4
  132.     JMP LOADFPP    ;10--put data in FPP
  133.     ;114 t cycles @ 4mHz = 28.5usec
  134.     ;
  135. FPPZERO:        ;x=0
  136.     XRA A
  137.     MOV C,A
  138.     MOV D,A
  139.     MOV E,A
  140.     ;a short cut, time not calculated
  141.     ;fall through to next routine
  142.     ;
  143.     ;
  144.     ;Data transfer routine
  145.     ;LOADFPP puts BD into fpp
  146. LOADFPP:
  147.     MOV A,E     ; 4
  148.     OUT DREG    ;11
  149.     MOV A,D     ; 4
  150.     OUT DREG    ;11
  151.     MOV A,C     ; 4
  152.     OUT DREG    ;11
  153.     MOV A,B     ; 4
  154.     OUT DREG    ;11
  155.     RET        ;10
  156.     ;70 t cycles = 17.5usec
  157.     ;
  158.     ;TOTAL TIME for C2AMD & LOADFPP = 46usec
  159.     ;
  160. ;**************************************************************
  161.     ;
  162.     ;
  163.     ;C2AMD found float to be out of range for FPP--warn & abort
  164. EXPHI:
  165.     LXI D,HIMSG
  166.     JMP ERREXIT
  167. EXPLO:
  168.     LXI D,LOMSG
  169. ERREXIT:
  170.     CALL PRMSG
  171.     JMP BOOT    ;bail out!
  172.     ;
  173.     ;
  174. HIMSG:    DB CR,LF,'float --> FPP exponent overflow ( > 2^63)$'
  175. LOMSG:    DB CR,LF,'float --> FPP exponent underflow ( < 2^-64)$'
  176.     ;
  177. ;**************************************************************
  178. ;**************************************************************
  179.     ;
  180.     ;
  181.     ;
  182.     ;FLD1 gets 1 float from the stack, puts it into fpp,
  183.     ;and DOES NOT restore stack.  Called by "intrinsic"
  184.     ;float arithmetic operations, e.g. fpmul and fpdiv.
  185. FLD1:
  186.     POP H        ;10--return addr for this block
  187.     SHLD RETADR    ;16
  188.     POP H        ;10--return addr for calling function
  189.     POP D        ;10
  190.     POP B        ;10--BD = argument
  191.     CALL C2AMD    ;17--convert format & load FPP
  192.     ;
  193.     PUSH H        ;11--restore return address of calling function
  194.     LHLD RETADR    ;16--return to calling function
  195.     PCHL        ; 4--  without disturbing stack
  196.     ;104 t cycles = 26usec, + 46 for C2AMD = 72usec
  197.     ;
  198. ;**************************************************************
  199.     ;
  200.     ;
  201.     ;FLOAD1 gets 1 float from the stack, puts it into fpp,
  202.     ;and restores stack for c80.  Called by "user-defined"
  203.     ;functions, not by fpmul or fpdiv.
  204. FLOAD1:
  205.     POP H        ;10--return addr for this block
  206.     SHLD RETADR    ;16
  207.     POP H        ;10--return addr for calling function
  208.     POP D        ;10
  209.     POP B        ;10--BD = argument
  210.     CALL C2AMD    ;17--convert format & load FPP
  211.     ;fix stack for c80
  212.     PUSH H        ;11
  213.     PUSH H        ;11
  214.     PUSH H        ;11--restore return address of calling function
  215.     LHLD RETADR    ;16--return to calling function
  216.     PCHL        ; 4--  without disturbing stack
  217.     ;126 t cycles = 31.5usec, + 46 for C2AMD = 77.5usec
  218.     ;
  219. ;**************************************************************
  220.     ;
  221.     ;
  222.     ;FLOAD2 gets 2 floats from the stack, puts them into fpp,
  223.     ;  and restores the stack for c80
  224. FLOAD2:
  225.     POP H        ;10--return addr for this block
  226.     SHLD RETADR    ;16
  227.     POP H        ;10--return addr for calling function
  228.     POP D        ;10
  229.     POP B        ;10--BD = second argument
  230.     CALL C2AMD    ;17--convert format & load FPP
  231.     POP D        ;10
  232.     POP B        ;10--BD = first argument
  233.     CALL C2AMD    ;17
  234.     ;fix stack for c80
  235.     PUSH H        ;11 x 5 = 55
  236.     PUSH H
  237.     PUSH H
  238.     PUSH H
  239.     PUSH H        ;restore return address of calling function
  240.     LHLD RETADR    ;16--return to calling function
  241.     PCHL        ; 4--  without disturbing stack
  242.     ;185 t cycles = 46.25usec, + 2 * 46 (for C2AMD) = 138.25usec
  243.     ;
  244. RETADR: DS 2        ;used by all FPP load routines
  245.     ;
  246. ;**************************************************************
  247. ;**************************************************************
  248.     ;
  249.     ;
  250.     ;
  251.     ;fpmask() allows the user to specify which error bits
  252.     ;are tested for error detection.  The argument to fpmask
  253.     ;becomes the ERRMASK that is ANDed with the status word 
  254.     ;to detect a hardware (FPP) error.
  255.  
  256.     PUBLIC fpmask
  257. fpmask: 
  258.     POP H        ;return address
  259.     POP B        ;argument
  260.     PUSH B        ;fix stack
  261.     PUSH H
  262.     MOV A,C     ;get the user-specified error mask
  263.     AN╔ ERRBIT╙    ╗ anΣ masδ ou⌠ al∞ bu⌠ thσ genuinσ erro≥ bits
  264.     STA ERRTEST+1
  265.     RET
  266.     ;
  267. ;**************************************************************
  268.     ;
  269.     ;
  270.     ;FPP Error handling routine
  271.     ;print message according to what sort of error occurred
  272. FPERR:
  273.     LXI D,EMSG0
  274.     CALL PRMSG    ;print general message
  275.     MOV C,A     ;save error code
  276.     MVI B,MSGPTR-ETYPES    ;# of codes to check
  277.     LXI H,ETYPES    ;M=first code in the list
  278.     LXI D,MSGPTR    ;(DE) = address that contains 
  279.             ;  location of message for first error code
  280. ERCHEK:
  281.     ANA M
  282.     JMP ERMATCH
  283.     MOV A,C     ;restore error code
  284.     INX H        ;advance to next code and message
  285.     INX D
  286.     INX D
  287.     DCR B
  288.     JNZ ERCHEK    ;more codes to test
  289.     ;should never fall through, but if it does, will print 'huh?'
  290.     ;
  291. ERMATCH:
  292.     XCHG        ;(HL) holds address of error message
  293.     MOV E,M
  294.     INX H
  295.     MOV D,M
  296.     JMP ERREXIT    
  297.     ;
  298.     ;
  299. EMSG0:    DB CR,LF,,LF,'FPP error:  $'
  300. EMSG1:    DB 'overflow$'
  301. EMSG2:    DB 'underflow$'
  302. EMSG3:    DB 'sqrt or log of negative number$'
  303. EMSG4:    DB 'divide by 0$'
  304. EMSG5:    DB 'argument of asin, acos, or exp too large$'
  305. EMSGX:    DB 'huh?$'    ;should never occur!
  306.     ;
  307.     ;
  308. ETYPES: DB OVRFLO,UNRFLO,TOOBIG,NEGARG,DIVZER
  309. MSGPTR: DW EMSG1,EMSG2,EMSG5,EMSG3,EMSG4,EMSGX
  310.     ;
  311. ;**************************************************************
  312. ;**************************************************************
  313.     ;
  314.     ;
  315.     ;Next come the hardware floating point routines themselves.
  316.     ;Thσ multiplcatioε routinσ contain≤ mos⌠ oµ wha⌠ thσ 
  317.     ;other routines use, so it is listed first.
  318.     PUBLIC    fpmul
  319. fpmul:
  320.     ;Note:    for fp multiply and divide,
  321.     ;c80 passes the first arg in the stack, the second in BD.
  322.     ;For the intrinsic multiply and divide operations, 
  323.     ;the calling program does NOT have to remove args 
  324.     ;from the stack upon return!  This is quite different from
  325.     ;the situation with user-defined functions.
  326.     ;
  327.     ;take 2nd arg from BD, convert to amd format, and pass to fpp
  328.     CALL C2AMD    ;17
  329.     ;take 1st arg from stack, convert format, and pass to fpp
  330.     CALL FLD1    ;17
  331.     ;send command, test for error, return with result in BD
  332.     MVI A,FMUL    ; 7
  333.     ;fall through to DOIT-ERRTEST-GETIT-AMD2C
  334.     ;
  335.     ;
  336.     ;DOIT-GETIT starts an FPP operation, tests for error,
  337.     ;gets the result & converts to c80 format
  338.     ;
  339.     ;send command in A to FPP
  340. DOIT:    OUT CREG    ;11--send command
  341. WAIT:    IN CREG     ;10
  342.     ORA A        ; 4
  343.     JM WAIT     ;10--until done
  344.     ;11 + n*24 t cycles = 2.75 + 6n usec (X)
  345.     ;
  346.     ;A contains error code
  347. ERRTEST:
  348.     ANI ERRBITS    ; 7--default = test all error bits
  349.     JNZ FPERR    ;10--if error found, else fall through to GETIT
  350.     ;
  351.     ;get top of fpp's stack into BD
  352. GETIT:
  353.     IN DREG     ;10
  354.     MOV B,A     ; 4
  355.     IN DREG     ;10
  356.     MOV C,A     ; 4
  357.     IN DREG     ;10
  358.     MOV D,A     ; 4
  359.     IN DREG     ;10
  360.     MOV E,A     ; 4
  361.     ;
  362.     ;Fall through to AMD2C, which converts FPP format in BD
  363.     ;to c80 float
  364.     ;AMD2C is based on suggestions by J.Shook, Electronics Lab, 
  365.     ;Dept.of Chemistry, SUNY Stony Brook
  366.     ;
  367. AMD2C:
  368.     MOV A,C     ; 4
  369.     ORA A        ; 4
  370.     JP C80ZERO    ;10--bit 7=0 implies value is 0
  371.     ;take care of mantissa sign
  372.     XRA B        ; 4--complements bit 7 of B, among other things
  373.     ANI 80H     ; 7--mask out all the garbage
  374.     XR┴ ├        ╗ 4--hΘ bi⌠ oµ ├ wa≤ ▒ iε AM─ format¼ s∩ this
  375.     MOV C,A     ; 4--  sets the hi bit of C to mantissa sign
  376.     ;take care of exponent sign
  377.     MVI A,40H    ; 7
  378.     ANA B        ; 4--is exponent negative?
  379.     MOV A,B     ; 4
  380.     JZ POSEXP    ;10--no, set hi bit to 1 (add 128)
  381.     ANI 7FH     ; 7--  yes, mask out hi bit
  382.     MOV B,A     ; 4
  383.     RET        ;10
  384.     ;
  385. POSEXP:
  386.     ORI 80H     ;set hi bit for positive exponent
  387.     MOV B,A
  388.     RET
  389.     ;format conversion delay identical whether exponent is + or -
  390.     ;
  391. C80ZERO:
  392.     XRA A
  393.     MOV B,A
  394.     RET
  395.     ;short cut--no time calculated
  396.     ;
  397.     ;(DOIT-ERRTEST-GETIT-AMD2C takes 156 t cycles 
  398.     ;  = 39usec, + X (for operation))
  399.     ;
  400.     ;41 t cycles = 10.25usec, + 46 (C2AMD) + 72 (FLD1) + 39 
  401.     ;  + X (DOIT) = 167.25 + X usec
  402.  
  403. ;
  404. ;float sqrt(x) float x;
  405.     PUBLIC    sqrt
  406. sqrt:
  407.     CALL FLOAD1
  408.     MVI A,FSQRT
  409.     JMP DOIT
  410.  
  411. ;float sin(x) float x;
  412.     PUBLIC    sin
  413. sin:
  414.     CALL FLOAD1
  415.     MVI A,FSIN
  416.     JMP DOIT
  417.  
  418. ;float cos(x) float x;
  419.     PUBLIC    cos
  420. cos:
  421.     CALL FLOAD1
  422.     MVI A,FCOS
  423.     JMP DOIT
  424.  
  425. ;float tan(x) float x;
  426.     PUBLIC    tan
  427. tan:
  428.     CALL FLOAD1
  429.     MVI A,FTAN
  430.     JMP DOIT
  431.  
  432. ;float asin(x) float x;   /* arc sin in radians */
  433.     PUBLIC    asin
  434. asin:
  435.     CALL FLOAD1
  436.     MVI A,FASIN
  437.     JMP DOIT
  438.  
  439. ;float acos(x) float x;
  440.     PUBLIC    acos
  441. acos:
  442.     CALL FLOAD1
  443.     MVI A,FACOS
  444.     JMP DOIT
  445.  
  446. ;float atan(x) float x;
  447.     PUBLIC    atan
  448. atan:
  449.     CALL FLOAD1
  450.     MVI A,FATAN
  451.     JMP DOIT
  452.  
  453. ;float log(x) float x;    /* log10 */
  454.     PUBLIC    log
  455. log:
  456.     CALL FLOAD1
  457.     MVI A,FLOG
  458.     JMP DOIT
  459.  
  460. ;float ln(x) float x;    /* log e */
  461.     PUBLIC    ln
  462. ln:
  463.     CALL FLOAD1
  464.     MVI A,FLN
  465.     JMP DOIT
  466.  
  467. ;float exp(x) float x;
  468.     PUBLIC    exp
  469. exp:
  470.     CALL FLOAD1
  471.     MVI A,FEXP
  472.     JMP DOITè
  473. ;float pwr(x,y) float x,y;    /* x to the yth power */
  474.     PUBLIC    pwr
  475. pwr:
  476.     CALL FLOAD2
  477.     ;
  478.     MVI A,XCHF
  479.     OUT CREG    ;11--send command
  480. PWAIT:    IN CREG     ;10
  481.     ORA A        ; 4
  482.     JM PWAIT    ;10--until done
  483.     ;
  484.     MVI A,FPWR
  485.     JMP DOIT
  486. ;
  487. ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  488. ;briefly back to the original source for fltlib--
  489. ;
  490. ; C/80 3.0 (7/7/83) - (c) 1983 Walter Bilofsky - used by permission
  491. ;
  492. pophrt: POP    H
  493.     RET
  494. ;
  495. ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  496. ;
  497. div10.:    CALL    movrf.    ;get facl_2 into BC, facl_ into DE
  498.     CALL    C2AMD    ;load 1st arg into fpp
  499.     LXI    B,8420H
  500.     LXI    D,0
  501.     CALL    C2AMD    ;load fpp with "10"
  502.     MVI    A,FDIV
  503.     CALL    DOIT    ;return with result in BCDE
  504.     PUSH    DE    ;in case needed later
  505.     ;save DE in facl_ & BC in facl_2,
  506.     ;  so ftoa gets proper value
  507.     CALL    movfr.    ;note:  destroys DE
  508.     POP    DE
  509.     RET        ;previously fell through to fpdiv
  510. ;
  511. ;the fdiv: routine is replaced by fpdiv:, and muldiv: is not needed
  512.  
  513.     PUBLIC    fpdiv
  514. fpdiv:
  515.     ;take 2nd arg from BD, convert to amd format, and pass to fpp
  516.     CALL C2AMD    ;17
  517.     ;take 1st arg from stack, convert format, and pass to fpp
  518.     CALL FLD1    ;17
  519.     ;swap fpp's A and B registers
  520.     MVI A,XCHF    ; 7
  521.     OUT CREG    ;11--send command
  522. DWAIT:    IN CREG     ;10
  523.     ORA A        ; 4
  524.     JM DWAIT    ;10--until done
  525.     ;send command, test for error, return with result in BD
  526.     MVI A,FDIV    ; 7
  527.     JMP DOIT    ;10
  528.     ;takes 169.75usec + X plus delay for register swap
  529.  
  530. ;END OF MODIFICATIONS TO FLTLIB.MAC<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  531. ;back to the original code again at mul10.:
  532. mul10.: CALL    movrf.
  533. ;
  534. ;END OF FL3.MAC
  535.